﻿#include "Common.h"


void FREELIST::Push(void* start, void* end, size_t n)
{
	if (end == nullptr) end = start;
	// 头插
	assert(start != nullptr);
	 
	*(void**)end = _freelist;
	_freelist = start;

	_size += n;
}

void* FREELIST::Pop()
{
	// 头删
	assert(_freelist != nullptr);

	void* obj = _freelist;
	_freelist = *(void**)obj;

	_size--;

	return obj;
}

void FREELIST::PopRange(void*& start, void*& end, size_t n)
{
	// 头删
	assert(_freelist != nullptr);

	start = end = _freelist;

	_size -= n;

	while (--n)
	{
		end = *(void**)end;
	}

	_freelist = *(void**)end;
	*(void**)end = nullptr;
}

bool FREELIST::Empty()
{
	return _freelist == nullptr;
}

size_t& FREELIST::InitSize()
{
	return _initsize;
}

size_t& FREELIST::Size()
{
	return _size;
}


size_t SizeIndex::Align(size_t bytes) // 返回对齐数
{
	if (bytes <= 128)
	{
		return _Align(bytes, 8);
	}
	else if (bytes <= 1024)
	{
		return _Align(bytes, 16);
	}
	else if (bytes <= 8 * 1024)
	{
		return _Align(bytes, 128);
	}
	else if (bytes <= 64 * 1024)
	{
		return _Align(bytes, 1024);
	}
	else if (bytes <= 256 * 1024)
	{
		return _Align(bytes, 8 * 1024);
	}
	else
	{
		return _Align(bytes, 8 * 1024);
	}
}

size_t SizeIndex::Index(size_t bytes) // 返回桶的下标
{
	if (bytes <= 128)
	{
		return _Index(bytes, 3);
	}
	else if (bytes <= 1024)
	{
		return _Index(bytes - 128, 4) + 16;
	}
	else if (bytes <= 8 * 1024)
	{
		return _Index(bytes - 1024, 7) + 16 + 56;
	}
	else if (bytes <= 64 * 1024)
	{
		return _Index(bytes - 8 * 1024, 10) + 16 + 56 + 56;
	}
	else if (bytes <= 256 * 1024)
	{
		return _Index(bytes - 64 * 1024, 13) + 16 + 56 + 56 + 56;
	}
	else
	{
		assert(false);
		return -1;
	}
}

size_t SizeIndex::_Align(size_t bytes, size_t alignNum)
{
	return (bytes + alignNum - 1) & ~(alignNum - 1);
}

size_t SizeIndex::_Index(size_t bytes, size_t shiftNum)
{
	return ((bytes + (1 << shiftNum) - 1) >> shiftNum) - 1;
}

size_t SizeIndex::maxBatch(size_t alignBytes)
{
	size_t batchsize = 256 * 1000 / alignBytes;
	if (batchsize < 2) return 2;
	if (batchsize > 512) return 512;
	return batchsize;
}

size_t SizeIndex::Bytes2Pages(size_t alignBytes)
{
	size_t batch_size = maxBatch(alignBytes);
	size_t pages = batch_size * alignBytes >> 13; // 申请空间对应的页数
	return pages == 0 ? 1 : pages;
}

// 整体控制在最多10%左右的内碎⽚浪费
// [1,128] 8byte对⻬ freelist[0,16)
// [128+1,1024] 16byte对⻬ freelist[16,72)
// [1024+1,81024] 128byte对⻬ freelist[72,128)
// [8*1024+1,641024] 1024byte对⻬ freelist[128,184)
// [64*1024+1,256*1024] 8*1024byte对⻬ freelist[184,208)





Spanlist::Spanlist()
{
	_head = new Span();
	_head->_next = _head;
	_head->_prev = _head;
}

void Spanlist::Insert(Span* pos, Span* span)
{
	assert(pos != nullptr);
	assert(span != nullptr);

	Span* prev = pos->_prev;
	prev->_next = span;
	span->_prev = prev;
	span->_next = pos;
	pos->_prev = span;
}

void Spanlist::Erase(Span* pos)
{
	assert(pos != nullptr);

	Span* prev = pos->_prev;
	Span* next = pos->_next;
	prev->_next = next;
	next->_prev = prev;
}

Span* Spanlist::Begin()
{
	return _head->_next;
}

Span* Spanlist::End()
{
	return _head;
}

std::mutex& Spanlist::Mtx()
{
	return _mtx;
}

bool Spanlist::Empty()
{
	return _head->_next == _head;
}

Span* Spanlist::PopFront()
{
	Span* ret = _head->_next;
	Erase(_head->_next);
	return ret;
}

void Spanlist::PushFront(Span* span)
{
	Insert(Begin(), span);
}


